
package org.acooke.uykfd.lastfm

import com.sun.jersey.api.client.Client
import com.sun.jersey.core.util.MultivaluedMapImpl

import java.lang.Integer
import java.sql.Connection

import org.acooke.uykfd.db.Schema

import scala.xml.XML

class TopTags(cnxn: Connection) {

  val ROOT = "http://ws.audioscrobbler.com/2.0/"
  val CLIENT = Client.create
  val API_KEY = Schema.PROPERTIES.orm.LASTFM_APIKEY(cnxn).getString
  val MIN_WEIGHT = Schema.PROPERTIES.orm.LASTFM_MINWEIGHT(cnxn).getInt
  val MUSIC = "music"

  val resource = CLIENT.resource(ROOT)
  resource.header("User-Agent", "uykdf andrew@acooke.org")
  
  def get(artist: String) = {
    println(artist)
    val params = new MultivaluedMapImpl()
    params.add("method", "artist.gettoptags")
    params.add("artist", artist)
    params.add("api_key", API_KEY)
    try {
      val xml = XML.loadString(resource.queryParams(params).get(classOf[String]))
      for (tagElement <- xml \\ "tag";
           val tag = tagElement \ "name" text;
           val weight = Integer.parseInt(tagElement \ "count" text);
           if weight >= MIN_WEIGHT)
        yield (tag, weight)
    } catch {
      case x: Exception => 
        println(x.getMessage)
        Nil
    }
  }

  def all(max_count: Int, max_rate: Double) = {
    val music = Schema.CANONICALS.orm.fromValue(MUSIC, cnxn)
    val start = System.currentTimeMillis
    var count = 0
    for (artist <- Schema.LFM_ARTIST_TAGS.orm.untaggedArtists(cnxn, max_count)) {
      val zero = count
      for ((tag, weight) <- get(artist.value)) {
        count += 1
        while (count / (System.currentTimeMillis - start) > max_rate / 1000) Thread.sleep(1000)
        val canonical = Schema.CANONICALS.orm.fromValue(tag, cnxn)
        Schema.LFM_ARTIST_TAGS.orm.raiseWeight(artist, weight, canonical, cnxn)
      }
      // instead of adding an empty loop, which marked an artist as having been checked,
      // but left some artists isolated, we now add a low weight link to "music" so to
      // guarantee a complete graph
      //if (count == zero) LastfmArtistTag.fromAll(canonical, 0, canonical, cnxn)
      // no we don't
      //Schema.LFM_ARTIST_TAGS.orm.raiseWeight(artist, 1, music, cnxn)
    }
  }

}
